export default class Vector2 {
  constructor(x = 0, y = 0) {
    this.x = x
    this.y = y
  }

  zero() {
    this.x = 0
    this.y = 0
  }

  clone() {
    return new Vector2(this.x, this.y)
  }

  add(t) {
    this.x += t.x || 0
    this.y += t.y || 0
  }

  addX(t) {
    this.x += t.x || 0
  }

  addY(t) {
    this.y += t.y || 0
  }

  addScalar(t = 0) {
    this.x += t
    this.y += t
  }

  addScalarX(t = 0) {
    this.x += t
  }

  addScalarY(t = 0) {
    this.y += t
  }

  sub(t) {
    this.x -= t.x || 0
    this.y -= t.y || 0
  }

  subX(t) {
    this.x -= t.x || 0
  }

  subY(t) {
    this.y -= t.y || 0
  }

  subScalar(t = 0) {
    this.x -= t
    this.y -= t
  }

  subScalarX(t = 0) {
    this.x -= t
  }

  subScalarY(t = 0) {
    this.y -= t
  }

  multiply(t) {
    this.x *= t.x || 1
    this.y *= t.y || 1
  }

  multiplyX(t) {
    this.x *= t.x || 1
  }

  multiplyY(t) {
    this.y *= t.y || 1
  }

  multiplyScalar(t = 1) {
    this.x *= t
    this.y *= t
  }

  multiplyScalarX(t = 1) {
    this.x *= t
  }

  multiplyScalarY(t = 1) {
    this.y *= t
  }

  divide(t) {
    // ! Cannot divide by zero !
    if (t.x !== 0 && t.y !== 0) {
      this.x /= t.x || 1
      this.y /= t.y || 1
    }
  }

  divideX(t) {
    // ! Cannot divide by zero !
    if (t.x !== 0) {
      this.x /= t.x || 1
    }
  }

  divideY(t) {
    // ! Cannot divide by zero !
    if (t.y !== 0) {
      this.y /= t.y || 1
    }
  }

  divideScalar(t) {
    // ! Cannot divide by zero !
    if (t !== 0) {
      this.x /= t || 1
      this.y /= t || 1
    }
  }

  divideScalarX(t) {
    // ! Cannot divide by zero !
    if (t !== 0) {
      this.x /= t || 1
    }
  }

  divideScalarY(t) {
    // ! Cannot divide by zero !
    if (t !== 0) {
      this.y /= t || 1
    }
  }

  getMagnitude() {
    return Math.sqrt(Math.pow(this.x, 2) + Math.pow(this.y, 2))
  }

  normalize() {
    this.divideScalar(this.getMagnitude())
  }

  randomize(i = new Vector2(1, 1)) {
    this.x = Math.random() * i.x
    this.y = Math.random() * i.y
  }

  addRandom(t = 0) {
    this.x += t - Math.random() * (2 * t)
    this.y += t - Math.random() * (2 * t)
  }

  addRandomX(t = 0) {
    this.x += t - Math.random() * (2 * t)
  }

  addRandomY(t = 0) {
    this.y += t - Math.random() * (2 * t)
  }

  lerp(t = this, i = 0.05) {
    this.x = (1 - i) * this.x + i * t.x
    this.y = (1 - i) * this.y + i * t.y
  }

  midpoint(i) {
    const e = new Vector2(this.x + i.x, this.y + i.y)
    e.divideScalar(2)
    return e
  }

  slope(t) {
    return ((t.y - this.y) / (t.x - this.x)) * -1
  }

  intercept(t) {
    return -t * this.x + this.y
  }

  distanceTo(t = this) {
    return Math.sqrt(Math.pow(t.x - this.x, 2) + Math.pow(t.y - this.y, 2))
  }

  angleTo(t = this, i = 'rad') {
    return i === 'rad'
      ? Math.atan2(t.y - this.y, t.x - this.x)
      : i === 'deg'
      ? (180 * Math.atan2(t.y - this.y, t.x - this.x)) / Math.PI
      : 0
  }
}
